package com.vitalfit.service.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vitalfit.client.FitnessPlanServiceClient;
import com.vitalfit.model.entity.user.User;
import com.vitalfit.repository.UserRepository;
import com.vitalfit.service.NotificationObserver;
import com.vitalfit.service.NotificationSubject;
import com.vitalfit.utils.TokenUtil;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class FitnessPlanExpiryNotificationSubjectImpl implements NotificationSubject {

    private final List<NotificationObserver> observers = new ArrayList<>();
    private final NotificationObserverImpl notificationObserver;
    private final FitnessPlanServiceClient fitnessPlanServiceClient;
    private final UserRepository userRepository;

    @PostConstruct
    public void init() {
        registerObserver(notificationObserver); // 注册观察者
    }

    @Override
    public void registerObserver(NotificationObserver o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(NotificationObserver o) {
        observers.remove(o);
    }

    @Override
    public void notifyObservers(String subject ,String message) {

        JSONObject tokenJSONObject = new JSONObject();
        tokenJSONObject.put("id", userRepository.findAllShopManagers()
                .stream()
                .findFirst()
                .map(User::getId));
        String token = TokenUtil.generateToken(JSON.toJSONString(tokenJSONObject));

        List<String> emails = fitnessPlanServiceClient
                .getCustomerEmailsByExpiringPlans(TokenUtil.generateToken(token));
        if (!emails.isEmpty()){
            observers.forEach(observer -> observer.sendBulkEmails(emails, subject, message));
        }
    }

    // This method could be called periodically or triggered by an event
    public void checkAndNotifyObservers() {
        notifyObservers("Fitness Plan Expiration Notification",
                "Your fitness plan will expire in less than a week. Please consider renewing it.");
    }


    @Scheduled(cron = "0 0 9 * * ?") // 每天早上9点执行
    public void scheduledCheckAndNotifyObservers() {
        checkAndNotifyObservers();
    }
}

